#include "asyncsubsctools.h"
#include "asyncsubscribe.h"

using namespace async_subscribe_tools;


///definition ACTION_LISTENER CLASS FUNCTION

action_listener::action_listener(const std::string& name)
    : name_(name)
{
}

void action_listener::on_failure(const mqtt::itoken& tok)
{
    std::cout << name_ << " failure";
    if (tok.get_message_id() != 0)
        std::cout << " (token: " << tok.get_message_id() << ")" << std::endl;
    std::cout << std::endl;
}

void action_listener::on_success(const mqtt::itoken& tok) {
    std::cout << name_ << " success";
    if (tok.get_message_id() != 0)
        std::cout << " (token: " << tok.get_message_id() << ")" << std::endl;
    if (!tok.get_topics().empty())
        std::cout << "\ttoken topic: '" << tok.get_topics()[0] << "', ..." << std::endl;
    std::cout << std::endl;
}



///definition CALLBACK CLASS FUNCTION

void callback::reconnect()
{
    usleep(1000);
    mqtt::connect_options connOpts;
    connOpts.set_keep_alive_interval(20);
    connOpts.set_clean_session(true);

    try {
        cli_.connect(connOpts, nullptr, *this);
    }
    catch (const mqtt::exception& exc) {
        std::cerr << "Error: " << exc.what() << std::endl;
        exit(1);
    }
}

// Re-connection failure
void callback::on_failure(const mqtt::itoken& tok)
{
    std::cout << "Reconnection failed." << std::endl;
    if (++nretry_ > 5)
        exit(1);
    reconnect();
}

// Re-connection success
void callback::on_success(const mqtt::itoken& tok)
{
    std::cout << "Reconnection success" << std::endl;;
    if(m_reciever)
    cli_.subscribe("hello", publish::AT_LEAST_ONCE, nullptr, listener_);
}

void callback::connection_lost(const std::string& cause)
{
    std::cout << "\nConnection lost" << std::endl;
    if (!cause.empty())
        std::cout << "\tcause: " << cause << std::endl;

    std::cout << "Reconnecting." << std::endl;
    nretry_ = 0;
    reconnect();
}

void callback::message_arrived(const std::string& topic, mqtt::message_ptr msg)
{
    std::cout << "Message arrived" << std::endl;
    std::cout << "\ttopic: '" << topic << "'" << std::endl;
    std::cout << "\t'" << msg->to_str() << "'\n" << std::endl;
        if(m_reciever)
            m_reciever->messageRecieved(topic, msg->to_str());
}

void callback::delivery_complete(mqtt::idelivery_token_ptr token) {}

callback::callback(mqtt::async_client& cli, action_listener& listener)
    : cli_(cli)
    , listener_(listener)
{

}

void callback::initSubscribe(AsyncSubscribe*  client)
{
    m_reciever = client;
}
